package com.synergy.stockflow.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.synergy.stockflow.constant.ResultCode;
import com.synergy.stockflow.entity.SysRole;
import com.synergy.stockflow.entity.SysRolePerm;
import com.synergy.stockflow.entity.SysUserRole;
import com.synergy.stockflow.exception.BusinessException;
import com.synergy.stockflow.mapper.SysRoleMapper;
import com.synergy.stockflow.mapper.SysRolePermMapper;
import com.synergy.stockflow.mapper.SysUserRoleMapper;
import com.synergy.stockflow.service.SysRoleService;
import com.synergy.stockflow.service.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Transactional
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {

    private final SysUserRoleMapper sysUserRoleMapper;
    @Autowired
    private SysRolePermMapper sysRolePermMapper;
    @Autowired
    private SysUserService sysUserService;

    @Autowired
    public SysRoleServiceImpl(SysUserRoleMapper sysUserRoleMapper) {
        this.sysUserRoleMapper = sysUserRoleMapper;
    }

    /**
     * 新增角色（不允许 roleCode 已存在）
     */
    @Override
    public boolean addRole(SysRole sysRole, List<Long> permIds) {
        Long currentUserId = sysUserService.currentUser().getId();
        Date now = new Date();

        String roleCode = sysRole.getRoleCode();
        if (roleCode == null || roleCode.trim().isEmpty()) {
            throw new BusinessException(ResultCode.BUSINESS_EXCEPTION, "角色编码（roleCode）不能为空");
        }
        roleCode = roleCode.trim();

        // 检查是否已存在相同 roleCode 的角色
        LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysRole::getRoleCode, roleCode);
        SysRole existingRole = this.getOne(queryWrapper);

        if (existingRole != null) {
            throw new BusinessException(ResultCode.BUSINESS_EXCEPTION, "角色编码 [" + roleCode + "] 已存在，无法重复添加");
        }

        // 设置创建信息
        sysRole.setRoleCode(roleCode);
        sysRole.setCreateBy(currentUserId);
        sysRole.setCreateTime(now);
        sysRole.setUpdateBy(currentUserId);
        sysRole.setUpdateTime(now);

        boolean saved = this.save(sysRole);
        if (!saved) {
            throw new BusinessException(ResultCode.BUSINESS_EXCEPTION, "角色新增失败");
        }

        Integer roleId = sysRole.getRoleId(); // MyBatis Plus 自动填充主键

        // 处理权限关联
        handleRolePerms(roleId, permIds, now);

        return true;
    }

    /**
     * 更新角色（必须存在，且不能更改 roleCode 到已存在的值）
     */
    @Override
    public boolean updateRole(SysRole sysRole, List<Long> permIds) {
        Long currentUserId = sysUserService.currentUser().getId();
        Date now = new Date();
        LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRole::getRoleCode, sysRole.getRoleCode());
        SysRole sysRoleDB = this.getOne(wrapper);
        Integer roleId = sysRoleDB.getRoleId();
        String roleCode = sysRole.getRoleCode();
        if (roleCode == null || roleCode.trim().isEmpty()) {
            throw new BusinessException(ResultCode.BUSINESS_EXCEPTION, "角色编码（roleCode）不能为空");
        }
        roleCode = roleCode.trim();

        // 检查角色是否存在
        SysRole existingRole = this.getById(roleId);
        if (existingRole == null) {
            throw new BusinessException(ResultCode.BUSINESS_EXCEPTION, "角色不存在，无法更新");
        }

        // 检查新的 roleCode 是否被其他角色占用（排除自己）
        LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysRole::getRoleCode, roleCode)
                .ne(SysRole::getRoleId, roleId); // 排除自身
        SysRole duplicate = this.getOne(queryWrapper);
        if (duplicate != null) {
            throw new BusinessException(ResultCode.BUSINESS_EXCEPTION, "角色编码 [" + roleCode + "] 已被其他角色使用");
        }

        // 更新基本信息
        sysRole.setRoleId(roleId);
        sysRole.setRoleCode(roleCode);
        sysRole.setUpdateBy(currentUserId);
        sysRole.setUpdateTime(now);

        boolean updated = this.updateById(sysRole);
        if (!updated) {
            throw new BusinessException(ResultCode.BUSINESS_EXCEPTION, "角色更新失败");
        }

        // 处理权限关联
        handleRolePerms(roleId, permIds, now);

        return true;
    }

    // 公共方法：处理角色-权限关联
    private void handleRolePerms(Integer roleId, List<Long> permIds, Date now) {
        // 删除旧权限
        LambdaQueryWrapper<SysRolePerm> deleteWrapper = new LambdaQueryWrapper<>();
        deleteWrapper.eq(SysRolePerm::getSysRoleId, roleId);
        sysRolePermMapper.delete(deleteWrapper);

        // 插入新权限
        if (permIds != null && !permIds.isEmpty()) {
            List<SysRolePerm> rolePerms = permIds.stream().map(permId -> {
                SysRolePerm rel = new SysRolePerm();
                rel.setSysRoleId(roleId);
                rel.setSysPermissionId(permId);
                rel.setCreateTime(now);
                return rel;
            }).collect(Collectors.toList());
            sysRolePermMapper.insert(rolePerms, 10); // 批量插入，每10条一批
        }
    }

    @Override
    public SysRole getByRoleCode(String roleCode) {
        LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysRole::getRoleCode, roleCode);
        return baseMapper.selectOne(queryWrapper);
    }

    @Override
    public boolean save(SysRole entity) {
        LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysRole::getRoleCode, entity.getRoleCode());
        queryWrapper.eq(SysRole::getRoleName, entity.getRoleName());
        List<SysRole> existed = baseMapper.selectList(queryWrapper);
        if (existed != null && !existed.isEmpty()) {
            throw new BusinessException(ResultCode.BUSINESS_EXCEPTION, "角色已存在");
        }
        return super.save(entity);
    }


    @Override
    public boolean removeById(Serializable id) {
        LambdaQueryWrapper<SysUserRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUserRole::getSysRoleId, id);
        List<SysUserRole> existed = sysUserRoleMapper.selectList(queryWrapper);
        if (existed != null && !existed.isEmpty()) {
            throw new BusinessException(ResultCode.BUSINESS_EXCEPTION, "用户正在使用该角色");
        }
        LambdaQueryWrapper<SysRolePerm> permWrapper = new LambdaQueryWrapper<>();
        permWrapper.eq(SysRolePerm::getSysRoleId, id);
        sysRolePermMapper.delete(permWrapper);
        return super.removeById(id);
    }

    @Override
    public int removeBatchByCodes(Collection<String> list) {
        LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
        if (list != null && !list.isEmpty()) queryWrapper.in(SysRole::getRoleCode, list);
        List<Integer> ids = baseMapper.selectList(queryWrapper).stream().map(SysRole::getRoleId).collect(Collectors.toList());
        LambdaUpdateWrapper<SysRolePerm> wrapper = new LambdaUpdateWrapper<>();
        if (!ids.isEmpty()) wrapper.in(SysRolePerm::getSysRoleId, ids);
        sysRolePermMapper.delete(wrapper);
        return baseMapper.delete(queryWrapper);
    }
}
